﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using thailandProject.Models;
using thailandProject.ViewModel;
using MvcFilters.Infrastructure.Filters;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Globalization;


namespace thailandProject.Controllers
{

    [ThailandAuthorize(1)]
    public class ReportingController : Controller
    {
        // GET: /Reporting/

        public ActionResult Index()
        {
            try
            {
                ViewBag.Header = "Reporting";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return View();
        }

        public ActionResult ViewApartmentReservations()
        {
            ApartmentReservationModel reservations = new ApartmentReservationModel();
            try
            {
                //changeable default values for the report
                bool defaultCheckBox = true;
                DateTime defaultFrom = DateTime.Now.AddMonths(-1);
                DateTime defaultTo = DateTime.Now.AddMonths(1);
                bool ascen = true;
                string sortType = "propName";
                string propName = "All";

                ViewBag.Header = "Apartment Reservations";
                ViewBag.from = defaultFrom;
                ViewBag.to = defaultTo;
                ViewBag.checkBox = defaultCheckBox;
                ViewBag.ascen = ascen;
                ViewBag.propName = propName;
                ViewBag.sortType = sortType;
                reservations = new ApartmentReservationModel(sortType, propName, defaultFrom, defaultTo, defaultCheckBox, ascen);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(reservations);
        }

        [HttpPost]
        public ActionResult ViewPickupTasks(FormCollection data)
        {
            List<PickupTasks> tasks = new List<PickupTasks>();
            try
            {

                DateTime from = Convert.ToDateTime(data["dateFrom"]);
                DateTime to = Convert.ToDateTime(data["dateTo"]);

                ViewBag.Header = "Pickup Tasks";
                ViewBag.from = from;
                ViewBag.to = to;

                tasks = ReportingMethods.getSortedPickupTaskList(from, to);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(tasks);

        }
        public ActionResult ViewPickupTasks()
        {
            List<PickupTasks> tasks = new List<PickupTasks>();
            try
            {
                //changeable default values for the report
                DateTime defaultFrom = DateTime.Now;
                DateTime defaultTo = DateTime.Now.AddMonths(1);

                ViewBag.Header = "Pickup Tasks";
                ViewBag.from = defaultFrom;
                ViewBag.to = defaultTo;

                tasks = ReportingMethods.getSortedPickupTaskList(defaultFrom, defaultTo);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(tasks);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult printPDF(string sortType, FormCollection data)
        {
            try
            {
                //create memorystream to hold the pdf being built

                string propName = (data["prop.selectedProp"] == null ? "All" : data["prop.selectedProp"].ToString());
                DateTime from = Convert.ToDateTime(data["dateFrom"]);
                DateTime to = Convert.ToDateTime(data["dateTo"]);
                bool showAll = Convert.ToBoolean(data["showAll"]);
                bool ascen = Convert.ToBoolean(data["ascen"]);


                ViewBag.Header = "Apartment Reservations";
                ViewBag.from = from;
                ViewBag.to = to;
                ViewBag.checkBox = showAll;
                ViewBag.ascen = ascen;
                ViewBag.propName = propName;

                List<ApartmentReservation> report = ReportingMethods.getSortedReservationList(sortType, propName, from, to, showAll, ascen);


                var output = new System.IO.MemoryStream();

                iTextSharp.text.Document doc = new iTextSharp.text.Document();
                iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, output);


                doc.SetMargins(50, 50, 50, 50);
                doc.SetPageSize(new iTextSharp.text.Rectangle(iTextSharp.text.PageSize.LETTER.Width, iTextSharp.text.PageSize.LETTER.Height));

                Font baseFont = new Font(Font.FontFamily.TIMES_ROMAN, 9, Font.NORMAL);
                Font headerFont = new Font(Font.FontFamily.TIMES_ROMAN, 10, Font.BOLD);
                Font titleFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD, BaseColor.BLUE);
                int columns = 7;

                doc.Open();

                //PDF content



                //add logo to pdf
                string imagePath = Server.MapPath("~") + "/images/logo.png";
                Image logo = Image.GetInstance(imagePath);
                doc.Add(logo);
                doc.AddTitle(ViewBag.Header);


                PdfPTable table = new PdfPTable(columns);
                int[] widths = new int[] { 1, 1, 1, 1, 1, 1, 1 };
                table.SetWidths(widths);
                //Table Header Cell
                PdfPCell cell = new PdfPCell(new Phrase(Element.ALIGN_MIDDLE, ViewBag.Header + " (" + ViewBag.from.ToString("MMM dd, yyyy") + " - " + ViewBag.to.ToString("MMM dd, yyyy") + ")", titleFont));
                cell.Colspan = columns;
                cell.HorizontalAlignment = Element.ALIGN_CENTER;
                cell.Border = Rectangle.BOTTOM_BORDER;
                table.AddCell(cell);

                //table headers

                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Property Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "First Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Last Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Start Date", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "End Date", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Quoted Price", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Paid", headerFont));


                RegionInfo thai = new RegionInfo("TH");
                foreach (var r in report)
                {

                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.propName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.clientFirstName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.clientLastName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.startDate.ToString("MMM dd, yyyy"), baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.endDate.ToString("MMM dd, yyyy"), baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.quotedPrice.ToString("C").Replace("$", "B "), baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.paid.ToString("C").Replace("$", "B "), baseFont));
                }

                doc.Add(table);

                doc.Close();


                Response.ContentType = "application/pdf";
                Response.AddHeader("Content-Disposition", "attachment;filename=CMAR_Report.pdf");
                Response.Buffer = true;
                Response.Clear();
                Response.OutputStream.Write(output.GetBuffer(), 0, output.GetBuffer().Length);
                Response.OutputStream.Flush();
                Response.End();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return File(Response.OutputStream, "application/pdf");

        }


        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult printPickupTaskPDF(FormCollection data)
        {
            try
            {
                //create memorystream to hold the pdf being built

                string propName = (data["prop.selectedProp"] == null ? "All" : data["prop.selectedProp"].ToString());
                DateTime from = Convert.ToDateTime(data["dateFrom"]);
                DateTime to = Convert.ToDateTime(data["dateTo"]);

                String first = "";
                String last = "";

                if (data["fname"] != null || data["lname"] != null)
                {
                    first = data["fname"].ToString();
                    last = data["lname"].ToString();
                }
             

                ViewBag.Header = "Pickup Tasks";
                ViewBag.from = from;
                ViewBag.to = to;
                ViewBag.propName = propName;

                List<PickupTasks> report = ReportingMethods.getSortedPickupTaskList(from, to);


                var output = new System.IO.MemoryStream();

                iTextSharp.text.Document doc = new iTextSharp.text.Document();
                iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, output);


                doc.SetMargins(50, 50, 50, 50);
                doc.SetPageSize(iTextSharp.text.PageSize.A4.Rotate()); //start with horizontal page
                
                Font baseFont = new Font(Font.FontFamily.TIMES_ROMAN, 9, Font.NORMAL);
                Font headerFont = new Font(Font.FontFamily.TIMES_ROMAN, 10, Font.BOLD);
                Font titleFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD, BaseColor.BLUE);


                int columns = 6;

                doc.Open();

                //PDF content

                //add logo to pdf
                string imagePath = Server.MapPath("~") + "/images/logo.png";
                Image logo = Image.GetInstance(imagePath);


                if (first != "" || last != "")
                {
                    //print client name on first page
                    doc.Add(logo);

                    Font bigFont;

                    if (first.Length <= 8 || last.Length <= 8)
                    {
                        bigFont = new Font(Font.FontFamily.HELVETICA, 148, Font.BOLD, BaseColor.BLUE);
                    }
                    else if ((first.Length < 12 && first.Length > 8) || (last.Length < 12 && last.Length > 8))
                    {
                        bigFont = new Font(Font.FontFamily.HELVETICA, 92, Font.BOLD, BaseColor.BLUE);
                    }
                    else
                    {
                        bigFont = new Font(Font.FontFamily.HELVETICA, 72, Font.BOLD, BaseColor.BLUE);
                    }

                    Phrase fn = new Phrase(first, bigFont);
                    Phrase ln = new Phrase("\n" + last, bigFont);
                    Paragraph p = new Paragraph(fn);
                    p.Add(ln);
                    p.SetLeading(0.9f, 0.9f);
                   // Paragraph fn = new Paragraph(first, bigFont);
                   // Paragraph ln = new Paragraph(last, bigFont);
                   // fn.Alignment = Element.ALIGN_CENTER;
                   p.Alignment = Element.ALIGN_CENTER;

                    
                    doc.Add(p);
                  

                    doc.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());

                    //change page to vertical
                    doc.SetPageSize(new iTextSharp.text.Rectangle(iTextSharp.text.PageSize.LETTER.Width, iTextSharp.text.PageSize.LETTER.Height));
                    doc.NewPage();
                }

                doc.SetPageSize(new iTextSharp.text.Rectangle(iTextSharp.text.PageSize.LETTER.Width, iTextSharp.text.PageSize.LETTER.Height));

                doc.Add(logo);
                doc.AddTitle(ViewBag.Header);

                PdfPTable table = new PdfPTable(columns);
                int[] widths = new int[] { 1, 1, 1, 1, 1, 1};
                table.SetWidths(widths);
                //Table Header Cell
                PdfPCell cell = new PdfPCell(new Phrase(Element.ALIGN_MIDDLE, ViewBag.Header + " (" + ViewBag.from.ToString("MMM dd, yyyy") + " - " + ViewBag.to.ToString("MMM dd, yyyy") + ")", titleFont));
                cell.Colspan = columns;
                cell.HorizontalAlignment = Element.ALIGN_CENTER;
                cell.Border = Rectangle.BOTTOM_BORDER;
                table.AddCell(cell);

                //table headers

                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Property Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "First Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Last Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Task Due Date", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Task Name", headerFont));
                table.AddCell(new Phrase(Element.ALIGN_MIDDLE, "Task Details", headerFont));



                RegionInfo thai = new RegionInfo("TH");
                foreach (var r in report)
                {

                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.propName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.clientFirstName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.clientLastName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.taskDueDate.ToString("MMM dd, yyyy"), baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.taskName, baseFont));
                    table.AddCell(new Phrase(Element.ALIGN_LEFT, r.taskDetails, baseFont));
                }

                doc.Add(table);

                doc.Close();


                Response.ContentType = "application/pdf";
                Response.AddHeader("Content-Disposition", "attachment;filename=CMAR_Report.pdf");
                Response.Buffer = true;
                Response.Clear();
                Response.OutputStream.Write(output.GetBuffer(), 0, output.GetBuffer().Length);
                Response.OutputStream.Flush();
                Response.End();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return File(Response.OutputStream, "application/pdf");

        }
        [HttpPost]
        public ActionResult ViewApartmentReservations(string sortType, FormCollection data)
        {
            ApartmentReservationModel reservations = new ApartmentReservationModel();
            try
            {
                string propName = (data["prop.selectedProp"] == null ? "All" : data["prop.selectedProp"].ToString());
                DateTime from = Convert.ToDateTime(data["dateFrom"]);
                DateTime to = Convert.ToDateTime(data["dateTo"]);
                bool showAll = Convert.ToBoolean(data["showAll"]);
                bool ascen = Convert.ToBoolean(data["ascen"]);


                ViewBag.Header = "Apartment Reservations";
                ViewBag.from = from;
                ViewBag.to = to;
                ViewBag.checkBox = showAll;
                ViewBag.ascen = ascen;
                ViewBag.Header = "Apartment Reservations";
                ViewBag.propName = propName;
                ViewBag.sortType = sortType;
                reservations = new ApartmentReservationModel(sortType, propName, from, to, showAll, ascen);
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(reservations);

        }

        [HttpGet]
        public ActionResult DoubleBookTest()
        {
            List<RESERVATION> collisions = null;
            try
            {
                ViewBag.Header = "Testing for double books...";
                //Select all reservations that are relevant. If they haven't start or end on/after today, get them
                ThailandEntities a = new ThailandEntities();
                DateTime now = DateTime.Now.Date;

                var ress = from res in a.RESERVATIONs
                           where res.resEndDate >= now
                           orderby res.propID, res.resStartDate
                           select res;
                RESERVATION[] curRes = ress.ToArray();
                collisions = new List<RESERVATION>();

                //For each reservation, see if there are any reservations of the same ID that overlap
                //Linear run time O(N)
                for (int i = 1; i < curRes.Length; i++)
                {
                    if (curRes[i].propID == curRes[i - 1].propID)
                    {
                        //See if these reservations overlap
                        if ((curRes[i].resEndDate > curRes[i - 1].resStartDate && curRes[i].resStartDate <= curRes[i - 1].resStartDate) ||
                            (curRes[i].resStartDate < curRes[i - 1].resEndDate && curRes[i].resEndDate >= curRes[i - 1].resEndDate) ||
                            (curRes[i].resStartDate >= curRes[i - 1].resStartDate && curRes[i].resEndDate <= curRes[i - 1].resEndDate) ||
                            (curRes[i].resStartDate < curRes[i - 1].resStartDate && curRes[i].resEndDate > curRes[i - 1].resEndDate))
                        {
                            //If res[i] ends after res[i - 1] begins AND res[i] starts before or on res[i - 1]'s start OR
                            //   res[i] starts before res[i - 1] ends AND res[i] ends after or on res[i - 1]'s end OR
                            //   res[i] begins after or on res[i - 1]'s start AND res[i] ends before or on res[i - 1]'s end OR
                            //   res[i] begins before res[i - 1] begins AND res[i] ends after res[i - 1] ends
                            collisions.Add(curRes[i - 1]);
                            collisions.Add(curRes[i]);
                        }//End to if reservations overlap
                    }//End to if propIDs are the same
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(collisions);
        }

        public ActionResult Accounting()
        {
            try
            {
                ViewBag.Header = "Accounting";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return View();

        }

        public ActionResult MoneyOwed()
        {
            try
            {
                ViewBag.Header = "Money Owed";
                string root = string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
                ViewBag.Root = root;
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return View();
        }

    }

}



